/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. All rights reserved.
 *
 */


import { expect } from '@jest/globals';
import * as fse from 'fs-extra';
import path from 'path';

import { OhosLogger } from '../../../../src/utils/log/ohos-logger';
import { ohosUnsupportService, runHvigor } from '../common';
import { ModuleBuildProfileModifier } from '../modifier/module-build-profile-modifier';

const LOG: OhosLogger = OhosLogger.getLogger('previewer.OPENLAB_AIDE_ZOS_Build_product_target_06_004.ts');

/**
 * 同步调用hvigor执行preview命令
 *
 * @param {string} projectDir 项目路径
 * @param {string[]} commands 命令
 */
export function runPreview(projectDir: string, commands: string[]) {
  // 执行preview
  const result = runHvigor(projectDir, commands);

  if (result.exitCode === 0) {
    LOG.info(`[run Preview successful] project: ${path.basename(projectDir)}\n params:'${commands.join(' ')}'\n`);
  } else {
    LOG.error(`[run Preview failed] project: ${path.basename(projectDir)}\n params:'${commands.join(' ')}'\n`);
  }

  // 判断runHvigor是否执行成功
  expect(result.exitCode).toEqual(0);
  return result;
}

export function generateDefaultFABuildConfig(projectDir: string, moduleName: string) {
  return {
    deviceType: 'default,tablet',
    checkEntry: 'true',
    localPropertiesPath: path.resolve(projectDir, 'local.properties'),
    Path: '',
    note: 'false',
    isPreview: 'true',
    hapMode: 'false',
    buildMode: 'debug',
    img2bin: 'true',
    projectProfilePath: path.resolve(projectDir, 'build-profile.json5'),
    watchMode: 'true',
    appResource: path.resolve(projectDir, moduleName, '.preview/default/intermediates/res/default/ResourceTable.txt'),
    logLevel: '3',
    aceManifestPath: path.resolve(
      projectDir, moduleName, '.preview/default/intermediates/manifest/default/MainAbility/manifest.json'),
    stageRouterConfig: {
      contents: [
        `{"module":{"pages":"$profile:main_pages","name":"${moduleName}"}}`,
        '{"src":[]}'
      ],
      paths: [
        path.resolve(projectDir, moduleName, '.preview/default/intermediates/res/default/module.json'),
        path.resolve(
          projectDir, moduleName, '.preview/default/intermediates/res/default/resources/base/profile/main_pages.json')
      ]
    },
    port: '29900',
    aceBuildJson: path.resolve(
      projectDir, moduleName, '.preview/default/intermediates/loader/default/MainAbility/loader.json'),
    aceModuleRoot: path.resolve(projectDir, moduleName, 'src/main/ets/MainAbility'),
    aceSoPath: path.resolve(projectDir, moduleName, '.preview/cache/nativeDependencies.txt'),
    cachePath: path.resolve(projectDir, moduleName, '.preview/cache'),
    aceModuleBuild: path.resolve(projectDir, moduleName, '.preview/intermediates/res/debug/rich/assets/js/MainAbility'),
    aceSuperVisualPath: path.resolve(projectDir, moduleName, 'src/main/supervisual/MainAbility')
  };
}

export function generateDefaultStageBuildConfig(projectDir: string, moduleName: string) {
  return {
    deviceType: 'default,tablet',
    checkEntry: 'true',
    localPropertiesPath: path.resolve(projectDir, 'local.properties'),
    Path: '',
    note: 'false',
    aceProfilePath: path.resolve(
      projectDir, moduleName, '.preview/default/intermediates/res/default/resources/base/profile'),
    isPreview: 'true',
    hapMode: 'false',
    buildMode: 'debug',
    img2bin: 'true',
    projectProfilePath: path.resolve(projectDir, 'build-profile.json5'),
    watchMode: 'true',
    appResource: path.resolve(projectDir, moduleName, '.preview/default/intermediates/res/default/ResourceTable.txt'),
    logLevel: '3',
    stageRouterConfig: {
      contents: [
        `{"module":{"pages":"$profile:main_pages","name":"${moduleName}"}}`,
        '{"src":["pages/Index"]}'
      ],
      paths: [
        path.resolve(projectDir, moduleName, '.preview/default/intermediates/res/default/module.json'),
        path.resolve(
          projectDir, moduleName, '.preview/default/intermediates/res/default/resources/base/profile/main_pages.json')
      ]
    },
    port: '29900',
    aceBuildJson: path.resolve(
      projectDir, moduleName, '.preview/default/intermediates/loader/default/loader.json'),
    aceModuleRoot: path.resolve(projectDir, moduleName, 'src/main/ets'),
    aceSoPath: path.resolve(projectDir, moduleName, '.preview/cache/nativeDependencies.txt'),
    cachePath: path.resolve(projectDir, moduleName, '.preview/cache'),
    aceModuleBuild: path.resolve(projectDir, moduleName, '.preview/default/intermediates/assets/default/ets'),
    aceSuperVisualPath: path.resolve(projectDir, moduleName, 'src/main/supervisual'),
    aceModuleJsonPath: path.resolve(projectDir, moduleName, '.preview/default/intermediates/res/default/module.json')
  };
}

/**
 * 预览测试用例公共命令行
 *
 * @param projectDir 项目路径
 * @param moduleName 模块名称
 * @param params 其他命令参数
 */
export function getPreviewTestCommonCommand(projectDir: string, moduleName: string, params?: string[]): string[] {
  const commands = ['-m', 'module',
    '-p', `module=${moduleName}`,
    '-p', 'buildRoot=.preview',
    '--debug'
  ];
  if (params) {
    for (const param of params) {
      commands.push('-p');
      commands.push(param);
    }
  }
  commands.push('buildPreviewerResource');
  commands.push('--no-daemon');
  return commands;
}

export function testPreview(
  projectDir: string, moduleName: string, pageType: string, buildConfig: any, params?: string[]) {
  const modulePath = path.resolve(projectDir, moduleName);
  const previewPath = path.resolve(modulePath, '.preview');
  const buildConfigPath = path.resolve(previewPath, 'config/buildConfig.json');
  fse.ensureFileSync(buildConfigPath);
  fse.writeJSONSync(buildConfigPath, buildConfig);
  const commands = ['-m', 'module',
    '-p', `module=${moduleName}@default`,
    '-p', 'product=default',
    '-p', `pageType=${pageType}`,
    '-p', 'compileResInc=true',
    '-p', 'buildRoot=.preview',
    '-p', 'previewMode=true',
  ];
  if (params) {
    for (const param of params) {
      commands.push('-p');
      commands.push(param);
    }
  }
  commands.push('PreviewBuild');

  ohosUnsupportService(projectDir, commands, moduleName);
  new ModuleBuildProfileModifier(projectDir, 'entry').updateTargetRuntimeOS('default', 'HarmonyOS');
  new ModuleBuildProfileModifier(projectDir, 'feature').updateTargetRuntimeOS('default', 'HarmonyOS');
  new ModuleBuildProfileModifier(projectDir, 'slibrary').updateTargetRuntimeOS('default', 'HarmonyOS');
  const result = runPreview(projectDir, commands);
  expect(fse.existsSync(previewPath)).toEqual(true);
  expect(result.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
}

/**
 * 构建并执行测试preview命令
 *
 * @param {string} projectDir 项目路径
 * @param {string} moduleName 模块名称
 * @param {string[]} params 其他命令参数
 */
export function testPreviewResource(projectDir: string, moduleName: string, params?: string[]) {
  const modulePath = path.resolve(projectDir, moduleName);
  const previewPath = path.resolve(modulePath, '.preview');
  const commands = getPreviewTestCommonCommand(projectDir, moduleName, params);
  const result = runPreview(projectDir, commands);
  expect(fse.existsSync(previewPath)).toEqual(true);
  expect(result.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
  return result;
}

/**
 * 元服务能力预览测试用例抽取
 *
 * @param projectDir 项目路径
 * @param moduleName 模块名
 * @param params 其他命令参数
 */
export function testPreviewForService(projectDir: string, moduleName: string, params?: string[]) {
  const modulePath = path.resolve(projectDir, moduleName);
  const previewPath = path.resolve(modulePath, '.preview');
  const commands = getPreviewTestCommonCommand(projectDir, moduleName, params);
  const modifyRuntimeOSResult = runHvigor(projectDir, commands);
  expect(fse.existsSync(previewPath)).toEqual(true);
  expect(modifyRuntimeOSResult.stdout.includes('BUILD SUCCESSFUL')).toBeTruthy();
}
